(function(angular) {
	'use strict';
	angular.module('fs.waf').factory('limitService', limitService)
	limitService.$inject = [ '$q', 'loggerFactory', 'commonService', 'ajaxServiceFactory', 'modalService', 'gridService', 'arithService', 'formatService'];
	function limitService($q, loggerFactory, commonService, ajaxServiceFactory, modalService, gridService, arithService, formatService) {
		var log = loggerFactory.getLogger("limitService"), ajaxService = ajaxServiceFactory.buildAjaxService({
			getLimitOptions : {
				url : 'do/cda/dataList/limitOptions',
				method : 'post'
			},
			getCategoryTree : {
				url : 'do/cda/category/cate/getCategoryTree',
				method : 'get'
			},
			getLayoutConfigByAttrId: {
				url : 'do/cda/limit/layout',
				method : 'post'					
			}
		});
		
		function initGeneral(initLimit, $scope, ctrl, updateProcessFlag) {
			var defer = $q.defer();
			var params = {};
			params.currentCcy = initLimit.limitCcy;
			ajaxService.getLimitOptions(params).then(function(response) {
				ctrl.limitCcyOptions = response.data.currencyOptions;
				ctrl.faceLimitCcyOptions = angular.copy(response.data.currencyOptions);
				ctrl.yesNoOptions = response.data.yesNoOptions;
				ctrl.overlimitAllowedOptions = angular.copy(response.data.yesNoOptions);
				ctrl.concentrationFlagOptions = angular.copy(response.data.yesNoOptions);
				ctrl.isUnlimitedOptions = angular.copy(response.data.yesNoOptions);
				ctrl.singleTxnLimitedOptions = {};
				ctrl.allSingleTxnLimitedOptions = response.data.singleTxnLimitedOptions;
				ctrl.limitRuleTypeOptions = response.data.limitRuleTypeOptions;
				ctrl.limitStatusOptions = response.data.limitStatusOptions;
				ctrl.currencyInfoOptions = response.data.currencyInfoOptions;
				ctrl.dataAction = response.data.dataAction;
				ctrl.limitRuleStatusOptions = response.data.limitRuleStatusOptions;
				
				//ctrl.faceLimitCcyOptions.callback = {"changed" : "vm.faceLimitCcyChanged"};
				//ctrl.overlimitAllowedOptions.callback = {"changed" : "vm.overlimitAllowedChanged"};
				//ctrl.concentrationFlagOptions.callback = {"changed" : "vm.concentrationFlagChanged"};
				//ctrl.singleTxnLimitedOptions.callback = {"changed" : "vm.singleTxnLimitedChanged"};
				//ctrl.isUnlimitedOptions.callback = {"changed" : "vm.isUnlimitedChanged"};
				defer.resolve();
			}, angular.noop);
		
			ctrl.bankIsFxMultiply = $scope.site.isFxMultiply;
			
			ctrl.faceLimitCcyChanged = function(value,a,b) {
				if(!b){
					if (ctrl.limit.faceLimitCcy) {
						// faceLimitCcy -> faceLimitFxrate
						ctrl.limit.faceLimitFxrate = formatService.formatNumber(getCurrencyFxrate(ctrl, ctrl.limit.faceLimitCcy), 'fxRate');
						ctrl.limit.limitAmt = 0;
						ctrl.limit.faceLimitAmt = 0;
						calculateAvailableAmt(ctrl, ctrl.limit.limitAmt);
					}
				}
			};
			
			//ctrl.faceLimitAmtOptions = {"callback" : {"changed" : "vm.faceLimitAmtChanged"}};
			ctrl.faceLimitAmtChanged = function(value, form, isInit) {
				if (!isInit) {
					if (ctrl.limit.faceLimitAmt) {
						// faceLimitAmt -> limitAmt,  Available Amount
						var limitAmt = 0;
						if (ctrl.bankIsFxMultiply == 'Y') {// bankIsFxMultiply from site
							limitAmt = arithService.mul(formatService.parseMoney(ctrl.limit.faceLimitAmt), formatService.parseNumber(ctrl.limit.faceLimitFxrate));
						} else {
							limitAmt = arithService.div(formatService.parseMoney(ctrl.limit.faceLimitAmt), formatService.parseNumber(ctrl.limit.faceLimitFxrate));
						}
						ctrl.limit.limitAmt = limitAmt;
						//
						calculateAvailableAmt(ctrl, limitAmt);
					}
				}
			};
			
			ctrl.overlimitAllowedChanged = function(value) {
				if (ctrl.limit.overlimitAllowed == 'N') {
					// overlimitAllowed -> overlimitPct
					ctrl.limit.overlimitPct = 0;
				}
			};
			
			ctrl.singleTxnLimitedChanged = function(value) {
				if (ctrl.limit.singleTxnLimited) {
					// singleTxnLimited -> singleTxnLimitAmt, singleTxnLimitPct
					if (ctrl.limit.singleTxnLimited == 'A') {
						ctrl.limit.singleTxnLimitPct = 0;
					} else if (ctrl.limit.singleTxnLimited == 'P') {
						ctrl.limit.singleTxnLimitAmt = 0;
					} else if (ctrl.limit.singleTxnLimited == 'N') {
						ctrl.limit.singleTxnLimitPct = 0;
						ctrl.limit.singleTxnLimitAmt = 0;
					} 
				}
			};
			
			ctrl.concentrationFlagChanged = function(value) {
				if (ctrl.limit.concentrationFlag == 'N') {
					// concentrationFlag -> concentrationPct
					ctrl.limit.concentrationPct = 0;
				}
			};
			
			ctrl.isUnlimitedChanged = function(value) {
				if (ctrl.limit.isUnlimited) {
					resetLimitByUnlimited(ctrl);
				}
			};
			
			ctrl.changeLayoutConfig = function(initLimit, action) {
				var defer = $q.defer();
				if (initLimit.limitNodeId) {
					var params = {'limitNodeId' : initLimit.limitNodeId, 'action' : action};
					ajaxService.getLayoutConfigByAttrId(params).then(function(response) {
						if("update" == action || "updateReject" == action || "updateContinue" == action){
							angular.forEach(response.data.formConfigs.general.gridConfigs, function(value, key) {
								if(value.hasOwnProperty("dynamicParameter")){
									value.readonly = "true";
								};
							});
						}
						ctrl.layoutConfig = response.data;
						 if(ctrl.validatorConfig) ctrl.validatorConfig.dynamicRules = response.data.dynamicRules;
						defer.resolve();
					});
				} 
				return defer.promise;
			};
			
			return defer.promise;
		}
		
		function resetLimitByUnlimited(ctrl) {
			if (ctrl.limit.isUnlimited == 'Y') {
				// concentrationFlag -> concentrationPct
				ctrl.limit.faceLimitCcy = ctrl.limit.limitCcy;
				ctrl.limit.faceLimitFxrate = formatService.formatNumber(getCurrencyFxrate(ctrl, ctrl.limit.faceLimitCcy), 'fxRate');
				ctrl.limit.limitAmt = formatService.formatMoney(0, ctrl.limit.limitCcy);
				ctrl.limit.faceLimitAmt = formatService.formatMoney(0, ctrl.limit.faceLimitCcy);
				ctrl.limit.limitAvailableAmt1 = 'Unlimited';
				
				ctrl.limit.limitWarnLine = 0;
				ctrl.limit.overlimitAllowed = 'N';
				ctrl.limit.concentrationFlag = 'N';
				
				
				// filter singleTxnLimitedOptions data
				var singleTxnLimitedDatas = [];
				for (var i = 0; i < ctrl.allSingleTxnLimitedOptions.length; i++) {
					var singleTxnLimitedOption = ctrl.allSingleTxnLimitedOptions[i];
					if (singleTxnLimitedOption.value != 'P') {
						singleTxnLimitedDatas.push(ctrl.allSingleTxnLimitedOptions[i]);
					}
				}
				ctrl.singleTxnLimitedOptions = singleTxnLimitedDatas;
				if (ctrl.limit.singleTxnLimited == 'P') ctrl.limit.singleTxnLimited = 'N';
				
				
			} else if (ctrl.limit.isUnlimited == 'N') {
				
				// filter singleTxnLimitedOptions data
				ctrl.singleTxnLimitedOptions = ctrl.allSingleTxnLimitedOptions;
			}
		}
		
		
		function getCurrencyFxrate(ctrl, ccyCode){
			var fxrate = 1.0;
			if(ctrl.currencyInfoOptions && ctrl.currencyInfoOptions) {
				for (var i = 0; i < ctrl.currencyInfoOptions.length; i++) {
					var currency = ctrl.currencyInfoOptions[i];
					if (ccyCode == currency.value) {
						if (currency.extProperty)
							fxrate = currency.extProperty;
						break;
					}
				}
			}
			return fxrate;
		}
		
		function getCurrencyDecimal(ctrl, ccyCode) {
			var decimal = 0;
			if(ctrl.currencyInfoOptions && ctrl.currencyInfoOptions) {
				for (var i = 0; i < ctrl.currencyInfoOptions.length; i++) {
					var currency = ctrl.currencyInfoOptions[i];
					if (ccyCode == currency.value) {
						if (currency.extProperty.decimalNum)
							decimal = currency.extProperty.decimalNum;
						break;
					}
				}
			}
			return decimal;
		}
		
		function calculateAvailableAmt(ctrl, limitAmt){
			var limitAmt = limitAmt || 0;
			var usedAmt = formatService.parseMoney(ctrl.limit.limitUsedAmt) || 0;
			var pendingAmt = formatService.parseMoney(ctrl.limit.limitPendingAmt) || 0;
			var availableAmt = 	arithService.lt(arithService.sub(limitAmt, usedAmt, pendingAmt), 0) ? 0: arithService.sub(limitAmt, usedAmt, pendingAmt);
			availableAmt = formatService.round(availableAmt, getCurrencyDecimal(ctrl, ctrl.limit.limitCcy));
			ctrl.limit.limitAvailableAmt = availableAmt;
		}
		
		function initLimitRule($scope, ctrl, updateProcessFlag) {
			//add sub data validator
			if(ctrl.validatorConfig) ctrl.layoutConfig.formConfigs.limitRule.tableConfigs.table.validatorConfig = ctrl.validatorConfig.limitRules;
			ctrl.limitRuleInnerGridOptions = gridService.createInnerGridOptions($scope, ctrl.layoutConfig.formConfigs.limitRule.tableConfigs.table, limitRuleRowSelectionChanged);
			ctrl.limitRuleInnerGridOptions.data = 'vm.limit.limitRules';
			ctrl.limitRuleInnerGridOptions.verifyData  = 'vm.limitOld.limitRules';
			function limitRuleRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedLimitRules = selectedRows;
			}
			
			ctrl.addLimitRule = function(currRow) {
				currRow.status = 'N';
			};
			
			ctrl.removeLimitRule = function() {		
				return $q(function(resolved, rejected){
					var hasAppliedRule = false;
					// remove from ctrl.product.profLimitFacis
					angular.forEach(ctrl.selectedLimitRules, function(selectedLimitRule, key) {
						angular.forEach(ctrl.limit.limitRules, function(limitRule, index) {
							if (limitRule.$$hashKey == selectedLimitRule.$$hashKey) {
								if (limitRule.status == 'A') {
									hasAppliedRule = true;
								}
							}
						});
					});
					if (hasAppliedRule) {
						modalService.openErrorDialogs({
							messages : [ 'limit.error.appliedrule-cannot-be-delete' ]
						});
						rejected();
					} else {
						// remove from ctrl.productTmp.profLimitFacis by framework
						resolved();
					}
				});
			};
			
		}
		function getCategoryTree() {
			var defer = $q.defer();
			ajaxService.getCategoryTree().then(function(response) {
				defer.resolve(response);
			});
			return defer.promise;
		}
		
		return {
			initGeneral : initGeneral,
			initLimitRule : initLimitRule,
			getCategoryTree : getCategoryTree,
			resetLimitByUnlimited : resetLimitByUnlimited
		};
	}
})(angular);